<!--
 * @Author: guo wei
 * @LastEditors: [guo wei]
 * @LastEditTime: 2024-01-24 16:46:22
 * @Description: 
-->
<template>
  <div class="table-wrap">
    <div class="form-header">
      <el-form :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label="">
          <el-input
            v-model="formInline.user"
            placeholder="输入名称/编号/其他搜索"
            clearable
          />
        </el-form-item>
        <el-form-item label="">
          <el-input
            v-model="formInline.region"
            placeholder="输入材料商名称搜索"
            clearable
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
          <el-button type="primary" @click="handleAdd">新增三级材料</el-button>
          <el-button type="warning">批量删除</el-button>
        </el-form-item>
      </el-form>
      <div class="operate-btn-wrap">
        <el-button type="primary">类别筛选</el-button>
        <el-button type="primary">批量导入</el-button>
        <el-button type="primary">导出Excel</el-button>
      </div>
    </div>
    <el-table
      ref="multipleTableRef"
      :data="tableData"
      style="width: 100%"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" />
      <el-table-column label="编号" prop="materialInfoId" width="105">
      </el-table-column>
      <el-table-column
        v-for="item in tableHeader"
        :key="item"
        :prop="item.prop"
        :label="item.name"
      >
        <template v-if="item.type == 'uploadImg'" #default="scope">
          <img
            v-if="scope.row[item.prop]"
            :src="scope.row[item.prop]"
            style="width: 80px; height: 60px"
            alt=""
          />
        </template>
      </el-table-column>
      <el-table-column fixed="right" label="操作" width="200">
        <template #default="scope">
          <el-button @click="copyRow(scope.row)" link type="primary"
            >复制</el-button
          >
          <el-button @click="handleEdit(scope.row)" link type="primary"
            >编辑</el-button
          >
          <el-button @click="handleDelete(scope.row)" link type="primary"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="600px"
      align-center
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <el-form
        ref="ruleFormRef"
        :model="ruleForm"
        :rules="rules"
        label-width="120px"
        class="demo-ruleForm"
        status-icon
      >
        <el-form-item
          v-for="item in tableHeader"
          :key="item"
          :label="item.name"
          :prop="item.prop"
        >
          <el-select
            @change="selectChange(item.prop)"
            :disabled="item.disabled ? item.disabled : false"
            v-if="item.type == 'select'"
            :multiple="item.multi ? true : false"
            v-model="ruleForm[item.prop]"
            placeholder=""
          >
            <el-option
              v-for="(key, idx) in item.options"
              :key="idx"
              :label="key.name"
              :value="key.id"
            />
          </el-select>
          <el-input
            v-if="item.type == 'input'"
            placeholder="请输入"
            v-model="ruleForm[item.prop]"
          ></el-input>
          <el-upload
            v-if="item.type == 'uploadImg' && !item.multi"
            class="upload-demo"
            action="#"
            :auto-upload="false"
            :file-list="ruleForm[item.prop]"
            :on-change="
              (file, fileList) => {
                handleUploadChange(item.prop, file, fileList);
              }
            "
            :limit="1"
            :on-exceed="handleExceed"
            :on-preview="handlePreview"
            :on-remove="handleRemove"
            list-type="picture"
          >
            <el-button type="primary">点击上传</el-button>
          </el-upload>
          <el-upload
            v-if="item.type == 'uploadImg' && item.multi"
            class="upload-demo"
            action="#"
            multiple
            :auto-upload="false"
            :file-list="ruleForm[item.prop]"
            :on-change="
              (file, fileList) => {
                handleMultiUploadChange(item.prop, file, fileList);
              }
            "
            :on-remove="handleMultiRemove"
            list-type="picture"
          >
            <el-button type="primary">点击上传</el-button>
          </el-upload>
          <NumberRange
            @inputfrom="getNumberRangeFrom"
            @inputto="getNumberRangeTo"
            :value="ruleForm[item.prop]"
            v-if="item.type == 'numberRange'"
          ></NumberRange>
          <el-cascader
            v-if="item.type == 'cascader'"
            v-model="ruleForm[item.prop]"
            :options="item.options"
            :props="props"
            @change="handleChange"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmForm"> 确认 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, reactive, computed, nextTick, onMounted } from "vue";
import {
  getMaterialInfos,
  getMaterialCategoryInfo,
  addMaterialInfo,
  getMaterialInfo,
  modifyMaterialInfo,
  deleteMaterialInfo,
  getPublicFileUrl,
} from "@/api/level-third";
import {
  allBuildingTypeInfo,
  gradeInfos,
  colorInfos,
} from "@/api/building-type.js";
import cache from "@/plugins/cache";
import { getFilesUrl } from "@/utils/index";
import * as qiniu from "qiniu-js";
import { getInitMultipartUploadWithPublic } from "@/api/login";
import SparkMD5 from "spark-md5";
import NumberRange from "@/components/InputNumberRange";
import { ElMessage, ElMessageBox } from "element-plus";

const publicFileUrl = ref("");

onMounted(() => {
  publicFileUrl.value = cache.session.getJSON("publicUrl");
  console.log(publicFileUrl.value);
});
const formInline = reactive({
  user: "",
  region: "",
  date: "",
});
const props = {
  multiple: true,
  value: "buildingTypeInfoId",
  label: "buildingTypeName",
};
const cascaderRef = ref();
const multipleTableRef = ref();
const multipleSelection = ref([]);
const toggleSelection = (rows) => {
  if (rows) {
    rows.forEach((row) => {
      multipleTableRef.value.toggleRowSelection(row);
    });
  } else {
    multipleTableRef.value.clearSelection();
  }
};
const handleSelectionChange = (val) => {
  multipleSelection.value = val;
};
const currentPage = ref(1);
const pageSize = ref(10);
const tableData = ref([]);
const largeLevelSelectedData = ref([]);
const primaryMaterialSelectedData = ref([]);
const secondaryMaterialSelectedData = ref([]);
const primaryMaterialDisabled = ref(true);
const secondaryMaterialDisabled = ref(true);
const tableHeader = ref([
  {
    prop: "materialCategoryName",
    name: "材料大类",
    type: "select",
    options: computed(() => largeLevelSelectedData.value),
  },
  {
    prop: "primaryMaterialName",
    name: "一级材料",
    type: "select",
    disabled: computed(() => primaryMaterialDisabled.value),
    options: computed(() => primaryMaterialSelectedData.value),
  },
  {
    prop: "secondaryMaterialName",
    name: "二级材料",
    type: "select",
    disabled: computed(() => secondaryMaterialDisabled.value),
    options: computed(() => secondaryMaterialSelectedData.value),
  },
  { prop: "materialName", name: "三级材料名称", type: "input" },
  { prop: "coverPage", name: "封面", type: "uploadImg", multi: false },
  // { prop: "tjxs", name: "推荐系数", type: "input" },
  { prop: "exampleUrl", name: "案例图", type: "uploadImg", multi: true },
  { prop: "price", name: "价格区间", type: "numberRange" },
  { prop: "technology", name: "工艺", type: "input" },
  {
    prop: "gradeName",
    name: "档次",
    type: "select",
    multi: true,
    options: computed(() => allGradeInfosData.value),
  },
  { prop: "suBlock", name: "SU贴图", type: "uploadImg", multi: true },
  {
    prop: "colorName",
    name: "颜色",
    type: "select",
    multi: true,
    options: computed(() => allColorInfosData.value),
  },
]);
const getListData = async () => {
  const params = { pageId: 1, pageSize: 20, count: true };
  try {
    const res = await getMaterialInfos(params);
    if (res.code == 200) {
      const temp =
        res.result.list.map(async (x) => {
          let exampleUrl =
            (x.materialExampleVOS &&
              x.materialExampleVOS.length > 0 &&
              x.materialExampleVOS[0].exampleUrl) ||
            "";
          const colorName =
            (x.materialColorInfoVOS &&
              x.materialColorInfoVOS.map((i) => i.colorName).join(",")) ||
            "";
          const gradeName =
            (x.materialGradeInfoVOS &&
              x.materialGradeInfoVOS.map((i) => i.gradeName).join(",")) ||
            "";

          let suBlock =
            (x.materialSuBlockVOS &&
              x.materialSuBlockVOS.length > 0 &&
              x.materialSuBlockVOS[0].suBlock) ||
            "";
          const price = (x.priceMin || "") + "-" + (x.priceMax || "");
          return {
            ...x,
            price,
            exampleUrl,
            suBlock,
            colorName,
            gradeName,
          };
        }) || [];

      const result = await Promise.all(temp);

      tableData.value = result;
    }
  } catch (error) {
    console.log("error", error);
  }
};
getListData();

const getIndex = (index) => {
  return (currentPage.value - 1) * pageSize.value + index + 1;
};
const dialogTitle = ref("添加材料");
const dialogType = ref("add");
const dialogVisible = ref(false);
const currentRowId = ref({});
const handleEdit = async (item) => {
  console.log("item", item);
  dialogTitle.value = "编辑材料";
  dialogType.value = "edit";
  currentRowId.value = item;
  dialogVisible.value = true;
  getMaterialInfoDetail(item.materialInfoId);
};
const getMaterialInfoDetail = async (id) => {
  try {
    const res = await getMaterialInfo(id);
    if (res.code == 200) {
      console.log("res", res);
      const data = res.result;
      ruleForm.materialCategoryName = data.materialCategory;
      ruleForm.primaryMaterialName = data.primaryMaterials;
      ruleForm.secondaryMaterialName = data.secondaryMaterials;
      ruleForm.materialName = data.materialName;

      ruleForm.coverPage = data.coverPage
        ? data.coverPage.split(",").map((url) => {
            return { url };
          })
        : [];
      ruleForm.exampleUrl = data.materialExampleVOS
        ? data.materialExampleVOS.map((x) => {
            return { url: x.exampleUrl };
          })
        : [];
      ruleForm.suBlock = data.materialSuBlockVOS
        ? data.materialSuBlockVOS.map((x) => {
            return { url: x.suBlock };
          })
        : [];

      ruleForm.price = [data.priceMin || "", data.priceMax || ""];
      ruleForm.technology = data.technology;
      ruleForm.gradeName =
        (data.materialGradeInfoVOS &&
          data.materialGradeInfoVOS.map((x) => x.gradeInfoId)) ||
        [];

      ruleForm.colorName =
        (data.materialColorInfoVOS &&
          data.materialColorInfoVOS.map((x) => x.colorInfoId)) ||
        [];
    }
  } catch (error) {}
};
const handleDelete = (item) => {
  ElMessageBox.confirm("确认删除此材料?", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      const res = await deleteMaterialInfo({
        materialInfoId: item.materialInfoId,
        recordVersion: item.recordVersion,
      });
      if (res.code == 200) {
        ElMessage({
          type: "success",
          message: "删除成功",
        });
        getListData();
      }
    })
    .catch(() => {
      ElMessage({
        type: "info",
        message: "取消删除",
      });
    });
};
const copyRow = (item) => {
  ElMessage({
    type: "success",
    message: "复制成功",
  });
  // setTimeout(() => {
  dialogTitle.value = "添加材料";
  dialogType.value = "add";
  dialogVisible.value = true;
  getMaterialInfoDetail(item.materialInfoId);
  // }, 1000);
  //  nextTick(() => {
  //   ruleFormRef.value.resetFields();
  // });
};
const handleAdd = () => {
  dialogTitle.value = "添加材料";
  dialogType.value = "add";
  dialogVisible.value = true;
  currentRowId.value = {};
  nextTick(() => {
    ruleFormRef.value.resetFields();
  });
};
// 上传相关
const handleExceed = (files) => {
  // upload.value.clearFiles()
  // const file = files[0]
  // file.uid = genFileId()
  // upload.value.handleStart(file)
  ElMessage({
    message: "只能上传一张图片,请先删除当前图片",
    type: "error",
  });
};
const handleUploadChange = (prop, file, files) => {
  for (let i = 0; i < files.length; i++) {
    const perobj = {
      percentage: 0,
      isshow: false,
    };
    // this.percenarr.push(perobj)
    if (files[i].size / 1024 > 1024 * 300) {
      ElMessage.error(`上传的第${i + 1}个视频超过300M！`);
    }
    let md5 = "";

    const sparkMD5 = new SparkMD5();
    const reader = new FileReader();
    reader.readAsText(file.raw);
    console.log("获取文件", file.raw);
    reader.onload = async (event) => {
      //获取文件MD5
      const str = event.target.result;
      sparkMD5.append(str);
      md5 = sparkMD5.end();

      const res = await getInitMultipartUploadWithPublic(md5);
      // 生成随机文件名，防止文件名冲突

      console.log("获取文件MD5", res);
      const key = res.result.encodedObjectName;
      if (res.result.isExist) {
        const tempFile = await getPublicFileUrl({ resourceKey: key });
        console.log("tempFile", tempFile);
        ruleForm[prop] = [{ url: tempFile.result || "" }];
        // ruleForm[prop] = files.map((url) => {
        //   return { url: tempFile.result || "" };
        // });
        return false;
        // return ElMessage.error("文件已存在，请重新上传");
      }
      const token = res.result.upToken;

      uploadfunc(prop, file, token, key, i);
    };
  }
};
const maxLength = ref(0);
const handleMultiUploadChange = (prop, file, files) => {
  let length = files.length;
  maxLength.value = Math.max(length, maxLength.value);
  setTimeout(() => {
    if (length === maxLength.value) {
      // 你的上传文件逻辑
      console.log("获取文件总共", files);
      ruleForm[prop] = [];
      for (let i = 0; i < files.length; i++) {
        const perobj = {
          percentage: 0,
          isshow: false,
        };
        // this.percenarr.push(perobj)
        if (files[i].size / 1024 > 1024 * 300) {
          ElMessage.error(`上传的第${i + 1}个视频超过300M！`);
        }
        let md5 = "";

        const sparkMD5 = new SparkMD5();
        const reader = new FileReader();
        reader.readAsText(files[i].raw);
        reader.onload = async (event) => {
          //获取文件MD5
          const str = event.target.result;
          sparkMD5.append(str);
          md5 = sparkMD5.end();

          const res = await getInitMultipartUploadWithPublic(md5);
          // 生成随机文件名，防止文件名冲突
          console.log("获取文件MD5", res);
          const key = res.result.encodedObjectName;
          if (res.result.isExist) {
            const tempFile = await getPublicFileUrl({ resourceKey: key });
            console.log("tempFile", tempFile);
            ruleForm[prop].push({ url: tempFile.result });
            // ruleForm[prop] = [{ url: tempFile.result || "" }];
            // ruleForm[prop] = files.map((url) => {
            //   return { url: tempFile.result || "" };
            // });
            return false;
            // continue;
            // return ElMessage.error("文件已存在，请重新上传");
          }
          const token = res.result.upToken;
          uploadMultiFunc(prop, file, token, key, i);
        };
      }
    }
  }, 100);
};
const uploadMultiFunc = async (prop, file, uploadtoken, key, i) => {
  console.log("执行了", i);
  const config = {
    useCdnDomain: true,
    domain: publicFileUrl.value,
    chunkSize: 10,
    forceDirect: false,
  };
  const putExtra = {
    fname: file.name, //文件原始文件名
    params: {},
    mimeType: "",
  };
  const observable = qiniu.upload(file.raw, key, uploadtoken, putExtra, config);
  observable.subscribe({
    next: (result) => {
      console.log("上传成功下一步。", result);
    },
    error: (err) => {
      //上传错误后触发
      console.log("上传失败", err);
    },
    complete: (result) => {
      console.log("上传成功后触发", result);
      //上传成功后触发。包含文件地址。
      if (result.code == 200) {
        ruleForm[prop].push({ url: publicFileUrl.value + result.result.key });
        // ruleForm[prop] = [result.result.key] || [];
        ElMessage({
          message: "上传成功",
          type: "success",
        });
      }
    },
  });
};
const uploadfunc = async (prop, file, uploadtoken, key, i) => {
  const config = {
    useCdnDomain: true,
    domain: publicFileUrl.value,
    chunkSize: 10,
    forceDirect: false,
  };
  const putExtra = {
    fname: file.name, //文件原始文件名
    params: {},
    mimeType: "",
  };
  const observable = qiniu.upload(file.raw, key, uploadtoken, putExtra, config);
  observable.subscribe({
    next: (result) => {
      console.log("上传成功下一步。", result);
    },
    error: (err) => {
      //上传错误后触发
      console.log("上传失败", err);
    },
    complete: (result) => {
      console.log("上传成功后触发", result);
      //上传成功后触发。包含文件地址。
      if (result.code == 200) {
        ruleForm[prop] =
          [{ url: publicFileUrl.value + result.result.key || "" }] || [];
        ElMessage({
          message: "上传成功",
          type: "success",
        });
      }
    },
  });
};
const onSubmit = () => {};
const ruleFormRef = ref();
const ruleForm = reactive({
  materialCategoryName: "",
  primaryMaterialName: "",
  secondaryMaterialName: "",
  materialName: "",
  coverPage: [],
  exampleUrl: [],
  price: [],
  technology: "",
  gradeName: [],
  suBlock: [],
  colorName: [],
});
const selectChange = (param) => {
  console.log("selectChange", param);
  if (param == "materialCategoryName") {
    primaryMaterialSelectedData.value = [];
    ruleForm.primaryMaterialName = "";
    secondaryMaterialSelectedData.value = [];
    ruleForm.secondaryMaterialName = "";
  }
  if (param == "primaryMaterialName") {
    secondaryMaterialSelectedData.value = [];
    ruleForm.secondaryMaterialName = "";
  }
};
watch(
  () => ruleForm.materialCategoryName,
  (newV) => {
    if (newV != "") {
      primaryMaterialDisabled.value = false;
      getSelectedDataByPrimaryLevel(newV);
    } else {
      primaryMaterialDisabled.value = true;
    }
  }
);
watch(
  () => ruleForm.primaryMaterialName,
  (newV) => {
    if (newV != "") {
      secondaryMaterialDisabled.value = false;
      getSelectedDataBySecondaryMaterial(newV);
    } else {
      secondaryMaterialDisabled.value = true;
    }
  }
);
const rules = reactive({});
const confirmForm = async () => {
  try {
    console.log("type", ruleForm, currentRowId.value);
    const temp = {
      ...ruleForm,
      coverPage: ruleForm.coverPage.length > 0 ? ruleForm.coverPage[0].url : "",
      exampleUrl: ruleForm.exampleUrl.join(""),
      // suBlock: ruleForm.suBlock.join(""),
      materialSuBlockDTOS: ruleForm.suBlock.map((x) => {
        return { suBlock: x.url };
      }),
      materialExampleDTOS: ruleForm.exampleUrl.map((x) => {
        return { exampleUrl: x.url };
      }),
      materialCategory: ruleForm.materialCategoryName,
      primaryMaterials: ruleForm.primaryMaterialName,
      secondaryMaterials: ruleForm.secondaryMaterialName,
      priceMax: ruleForm.price.length > 0 ? ruleForm.price[1] : "",
      priceMin: ruleForm.price.length >= 0 ? ruleForm.price[0] : "",
      materialColorInfoDTOS: allColorInfosData.value
        .filter((x) => ruleForm.colorName.indexOf(x.id) != -1)
        .map((x) => {
          return { colorInfoId: x.id };
        }),
      materialGradeInfoDTOS: allGradeInfosData.value
        .filter((x) => ruleForm.gradeName.indexOf(x.id) != -1)
        .map((x) => {
          return { gradeInfoId: x.id };
        }),
    };

    delete temp.materialCategoryName;
    delete temp.primaryMaterialName;
    delete temp.secondaryMaterialName;
    delete temp.suBlock;
    delete temp.exampleUrl;
    delete temp.price;
    delete temp.colorName;
    delete temp.gradeName;
    console.log("type", temp);
    if (dialogType.value == "add") {
      const res = await addMaterialInfo(temp);
      if (res.code == 200) {
        ElMessage({
          type: "success",
          message: "新增成功",
        });
        dialogVisible.value = false;
        getListData();
      }
    } else {
      const param = {
        ...temp,
        recordVersion: currentRowId.value.recordVersion,
        materialInfoId: currentRowId.value.materialInfoId,
      };
      const res = await modifyMaterialInfo(param);
      if (res.code == 200) {
        ElMessage({
          type: "success",
          message: "修改成功",
        });
        dialogVisible.value = false;
        getListData();
      }
    }
  } catch (error) {}
};
const getNumberRangeFrom = (data) => {
  ruleForm.price[0] = Number(data);
};
const getNumberRangeTo = (data) => {
  ruleForm.price[1] = Number(data);
};
const getSelectedDataByLevel = async (parentId) => {
  try {
    const res = await getMaterialCategoryInfo({ parentId });
    if (res.code == 200) {
      largeLevelSelectedData.value =
        res.result.map((x) => {
          return { id: x.materialCategoryInfoId, name: x.materialCategoryName };
        }) || [];
    }
  } catch (error) {}
};
const getSelectedDataByPrimaryLevel = async (parentId) => {
  try {
    const res = await getMaterialCategoryInfo({ parentId });
    if (res.code == 200) {
      primaryMaterialSelectedData.value =
        res.result.map((x) => {
          return { id: x.materialCategoryInfoId, name: x.materialCategoryName };
        }) || [];
    }
  } catch (error) {}
};
const getSelectedDataBySecondaryMaterial = async (parentId) => {
  try {
    const res = await getMaterialCategoryInfo({ parentId });
    if (res.code == 200) {
      secondaryMaterialSelectedData.value =
        res.result.map((x) => {
          return { id: x.materialCategoryInfoId, name: x.materialCategoryName };
        }) || [];
    }
  } catch (error) {}
};
const allBuildingTypeInfoData = ref([]);
const allGradeInfosData = ref([]);
const allColorInfosData = ref([]);
const getAllBuildingTypeInfo = async () => {
  try {
    const res = await allBuildingTypeInfo();
    if (res.code == 200) {
      allBuildingTypeInfoData.value = res.result || [];
    }
  } catch (error) {}
};
const getAllGradeInfos = async () => {
  try {
    const res = await gradeInfos();
    if (res.code == 200) {
      allGradeInfosData.value =
        res.result.list.map((x) => {
          return {
            id: x.gradeInfoId,
            name: x.gradeName,
          };
        }) || [];
    }
  } catch (error) {}
};
const getAllColorInfos = async () => {
  try {
    const res = await colorInfos();
    if (res.code == 200) {
      allColorInfosData.value =
        res.result.list.map((x) => {
          return {
            id: x.colorInfoId,
            name: x.colorName,
          };
        }) || [];
    }
  } catch (error) {}
};
getSelectedDataByLevel(-1);
getAllBuildingTypeInfo();
getAllGradeInfos();
getAllColorInfos();
// tableHeader.value = tableHeader.value.map(async (x) => {
//   if (x.prop == "materialCategoryName") {
//     return { ...x, options: result };
//   }
//   return x;
// });
</script>
<style lang="scss" scoped>
.table-wrap {
  padding: 20px;
  .form-header {
    display: flex;
    justify-content: space-between;
  }
}
.demo-ruleForm {
  width: 100%;
  .el-select {
    width: 100%;
  }
}
</style>
